package com.lej.core.base

import android.os.Bundle
import androidx.annotation.LayoutRes
import androidx.appcompat.app.AppCompatActivity
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.LiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.qmuiteam.qmui.util.QMUIStatusBarHelper
import com.qmuiteam.qmui.widget.dialog.QMUITipDialog
import java.lang.reflect.ParameterizedType

/**
 * 一个拥有DataBinding框架的基Activity
 * 这里根据项目业务可以换成你自己熟悉的BaseActivity, 但是需要继承RxAppCompatActivity,方便LifecycleProvider管理生命周期
 */
abstract class BaseActivity<V : ViewDataBinding, VM : ViewModel> : AppCompatActivity(), IBaseView {
    protected lateinit var binding: V
    protected lateinit var viewModel: VM
    private var viewModelId = 0
    private var tipDialog: QMUITipDialog? = null //提示dialog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        viewModelId = initVariableId()
        viewModel = initViewModel()

        //页面接受的参数方法
        initParam()
        //私有的初始化DataBinding和ViewModel方法
        initViewDataBinding()
        //私有的ViewModel与View的契约事件回调逻辑
        registerUIChangeLiveDataCallBack()
        //页面数据初始化方法
        QMUIStatusBarHelper.setStatusBarLightMode(this)
        initData()
        //页面事件监听的方法，一般用于ViewModel层转到View层的事件注册
        initViewObservable()
    }

    override fun onDestroy() {
        super.onDestroy()
        binding.unbind()
      }

    /**
     * 注入绑定
     */
    private fun initViewDataBinding() {
        //DataBindingUtil类需要在project的build中配置 dataBinding {enabled true }, 同步后会自动关联android.databinding包
        binding = DataBindingUtil.setContentView(this, getLayout())
        binding.lifecycleOwner = this

        //关联ViewModel
        binding.setVariable(viewModelId, viewModel)
        //让ViewModel拥有View的生命周期感应
        if (viewModel is BaseViewModel<*>) {
            lifecycle.addObserver((viewModel as BaseViewModel<*>?)!!)
            //注入RxLifecycle生命周期
            (viewModel as BaseViewModel<*>).injectLifecycleProvider(this)
        }
    }

    //刷新布局
    fun refreshLayout() {
        binding.setVariable(viewModelId, viewModel)
    }

    /* ===================================================================== */ //注册ViewModel与View的契约UI回调事件
    protected open fun registerUIChangeLiveDataCallBack() {
        (viewModel as? BaseViewModel<*>)?.let { viewModel ->
            viewModel.uC.run {
                //加载对话框显示
                showDialogEvent?.addObserver(::showLoading)
                //加载对话框消失
                dismissDialogEvent?.addObserver { disDialog() }
                //关闭界面
                finishEvent?.addObserver { finish() }
                //关闭上一层
                onBackPressedEvent?.addObserver { onBackPressed() }
            }
        }
    }

    @JvmOverloads
    fun showLoading(tips: String? = null) {
        tipDialog?.takeIf { it.isShowing }?.dismiss()
        tipDialog = QMUITipDialog.Builder(this)
            .setIconType(QMUITipDialog.Builder.ICON_TYPE_LOADING)
            .setTipWord(tips)
            .create()
        tipDialog?.setCancelable(false)
        tipDialog?.show()
    }

    fun disDialog() {
        tipDialog?.takeIf { it.isShowing }?.dismiss()
    }

    /* ===================================================================== */
    override fun initParam() {}

    /**
     * 初始化根布局
     *
     * @return 布局layout的id
     */
    @LayoutRes
    abstract fun getLayout(): Int

    /**
     * 初始化ViewModel的id
     *
     * @return BR的id
     */
    abstract fun initVariableId(): Int

    /**
     * 初始化ViewModel
     *
     * @return 继承BaseViewModel的ViewModel
     */
    @Suppress("UNCHECKED_CAST")
    open fun initViewModel(): VM {
        val modelClass: Class<ViewModel>
        val type = javaClass.genericSuperclass
        modelClass = if (type is ParameterizedType) {
            type.actualTypeArguments[1] as Class<ViewModel>
        } else {
            //如果没有指定泛型参数，则默认使用BaseViewModel
            BaseViewModel::class.java as Class<ViewModel>
        }
        viewModel = createViewModel(this, modelClass) as VM
        return viewModel
    }

    override fun initData() {}
    override fun initViewObservable() {}

    /**
     * 创建ViewModel
     */
    private fun <T : ViewModel> createViewModel(activity: FragmentActivity?, cls: Class<T>): T {
        return ViewModelProvider(activity!!).get(cls)
    }

    protected fun <T> LiveData<T>.addObserver(observer: Observer<T>) {
        observe(this@BaseActivity, observer)
    }
}